package p.ithorns.framework.common.codec;

import java.util.zip.CRC32;

/**
 * CRC32Codec
 *
 * @author ithorns
 * @version 1.0
 * @date 2020/4/7 13:13
 */
public class CRC32Codec {

    /**
     * 一个字节包含位的数量 8
     */
    private static final int BITS_OF_BYTE = 8;

    public static int crc32ByJdk(byte[] data) {
        CRC32 crc32 = new CRC32();
        crc32.update(data);
        return (int) crc32.getValue();
    }

    /**
     * 5.0文档提供算法
     *
     * @param data -
     * @return -
     */
    public static int imageCrc32(byte[] data) {
        if (null == data || data.length == 0) {
            return ~0;
        }

        int crc = 0xFFFFFFFF;
        int size = data.length;
        for (int i = 0; i < size; i++) {
            crc ^= data[i];
            for (int j = BITS_OF_BYTE; j > 0; j--) {
                crc = (crc >> 1) ^ (0xEDB88320 & ((crc & 1) == 1 ? 0xFFFFFFFF : 0));
            }
        }
        return ~crc;
    }

    public static int crc32(byte[] data) {
        int crc = 0xffffffff;
        int length = data.length;
        for (int j = 0; j < length; j++) {
            crc ^= data[j];
            for (byte i = 0; i < 8; ++i) {
                if ((crc & 1) != 0) {
                    // 0xEDB88320= reverse 0x04C11DB7
                    crc = (crc >> 1) ^ 0xEDB88320;
                }
                else {
                    crc = (crc >> 1);
                }
            }
        }
        return ~crc;
    }

    public static int crc32Mpeg2(byte[] data) {
        byte i;
        int crc = 0xffffffff;
        int length = data.length;
        for (int j = 0; j < length; j++) {
            crc ^= data[j] << 24;
            for (i = 0; i < 8; ++i) {
                if ((crc & 0x80000000) != 0) {
                    crc = (crc << 1) ^ 0x04C11DB7;
                } else {
                    crc <<= 1;
                }
            }
        }
        return crc;
    }


    /*uint32_t crc32_compute(uint8_t const * p_data, uint32_t size, uint32_t const * p_crc)
{
    uint32_t crc;

    crc = (p_crc == NULL) ? 0xFFFFFFFF : ~(*p_crc);
    for (uint32_t i = 0; i < size; i++)
    {
        crc = crc ^ p_data[i];
        for (uint32_t j = 8; j > 0; j--)
        {
            crc = (crc >> 1) ^ (0xEDB88320U & ((crc & 1) ? 0xFFFFFFFF : 0));
        }
    }
    return ~crc;
}

uint16_t crc16_compute(uint8_t const * p_data, uint16_t size, uint16_t const * p_crc)
{
    uint16_t crc;

    crc = (p_crc == NULL) ? 0xFFFF : ~(*p_crc);
    for (uint16_t i = 0; i < size; i++)
    {
        crc = crc ^ p_data[i];
        for (uint8_t j = 8; j > 0; j--)
        {
            crc = (crc >> 1) ^ (0x1021U & ((crc & 1) ? 0xFFFF : 0));
        }
    }
    return ~crc;
}*/
}